package view;

import java.rmi.RemoteException;
import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JTable;

import controller.FirewallSession;
import server.FirewallException;
import server.Log;

/**
 * Class is responsible for FW logger table.
 * Table size, column names are defined.
 */
public class LoggerTable extends AbstractLoggerTable
{
	/**
	 * Serial version ID - for serialization
	 */
	private static final long serialVersionUID = -1077083104420394516L;

	/**
	 * server controller
	 */
	public FirewallSession UI;
	
	/**
	 * Current logger table
	 */
	public static LoggerTable currentLoggerTable = null;
	
	/**
	 * Column names
	 */
	private final static String columnNames[] = 
		{"Time", /*"Rule Type",*/ "Direction", "Source IP", "Source Port","Destination IP",
		 "Destination Port", "Protocol", "Rule port", "Rule protocol", "Status"};
	      
	/**
	 * C'tor - Table with specified controller and size is created.
	 * Fill the table with the FW logger information.
	 * @param ui	- the controller for the system actions
	 */
	public LoggerTable(FirewallSession ui)
	{
		super(Settings.windowDepth, columnNames.length);
		this.UI = ui;
		currentLoggerTable = this;
	    setAutoResizeMode (JTable.AUTO_RESIZE_OFF);
		buildTable();
	}
	
	/** 
	 * @return the names of the table columns
	 */
	public String[] getColumnNames()
	{
		return columnNames;
	}
	
	/**
	 * Fill the table with logger data.
	 * @param objectData - the logger data to put to the table
	 */
	public void fillTable(Object[] objectData)
	{
		Log[] loggerData = (Log[])objectData;
		
		/* Statistics counters */
		Settings.statsAccepted = 0;
		Settings.statsDenied = 0;
	
		/* Fill the data in table from received */
		int j = 0;
		for(int i = 0; i < loggerData.length; i++)
		{
			/* Check if data is valid */
			if(loggerData[i] != null)
			{
				j = 0;
				/* Put the time in the time format*/
				this.setValueAt(new Date(loggerData[i].time * Globals.MSEC), i, j++);
				/* Put the direction */
				this.setValueAt(loggerData[i].direct,   	i, j++);
				/* Put the source IP */
				this.setValueAt(loggerData[i].sourceIp,		i, j++);
				/* Put the source port */
				this.setValueAt(loggerData[i].sourcePort,  	i, j++);
				/* Put the distination IP */
				this.setValueAt(loggerData[i].destIp,   	i, j++);
				/* Put the distination port */
				this.setValueAt(loggerData[i].destPort,  	i, j++);
	
				/* Put the protocol if needed */
				if (loggerData[i].protocol == null ||  loggerData[i].protocol.equals(""))
	    	    { 
	    	        j++;
	    	    }
	    	    else{
	    	    	this.setValueAt(loggerData[i].protocol,  i, j++);
				}
				
				
				/* Put the rule port/protocol if needed */
				if (loggerData[i].ruleProtocol == null ||  loggerData[i].ruleProtocol.equals(""))
	    	    {
	    	        j += 2;
				}
				else{
					this.setValueAt(loggerData[i].rulePort,      i, j++);
					this.setValueAt(loggerData[i].ruleProtocol,  i, j++);
				}
				
	
				/* Put the report */
				this.setValueAt(loggerData[i].action,  i, j++);
				
				/* Statistic update */
				switch(loggerData[i].action)
				{
				case DENY:
					Settings.statsDenied++;
					break;
				case ACCEPT:
					Settings.statsAccepted++;
					break;					
				}				
			}
			else /* Data isn't valid - read the next row */
			{
				/* N/A */
				continue;
			}
		}
	}
	
	/**
	 * Get the data from UI.
	 * @return the logger data from server
	 */
	public Object[] getLoggerData()
	{
		/* Take the data according to filter type */
		Log[] log = null;
		try {
			Integer days = Settings.historyDepth;
			switch(Settings.currentFilterType)
			{
			/* All data with specified history */
			case ALL:
				log= UI.getLogs(days, null, null, null,null,null );
				break;
			/* All data with specified history and protocol */
			case PROTOCOL:
				log= UI.getLogs(days, Log.typeOpt.CONTEXT, Settings.filterProtocol, null,null,null );
				break;
			/* All data with specified IP, Port, direction */
			case IP:
				log = UI.getLogs(days, Log.typeOpt.IP, null, Settings.filterIP, Settings.filterPort, Settings.filterDir );
				break;
			}
		} catch (RemoteException e) {
			ErrorFrame.AddError("Failed to get log data:" + e.getMessage(), new JFrame());
		} catch (FirewallException e) {
			ErrorFrame.AddError("Failed to get log data:"  + e.getMessage(), new JFrame());
		}
		
		return log;
	}
	
	/**
	 * Get the table name.
	 * @return the logger table name
	 */
	protected String getTableName()
	{
		return "Sessions Logger";
	}
}
